import java.util.HashMap;
import java.util.LinkedList;

public class AvailableTrades extends HashMap<String, Offer> {

	private final static String CASH = "CASH";
	private List<Offer> log;

	boolean verifyOffer(Offer o){

		if(o == null) return false;

		//OFFERID, TRADERNAME, TRANSTYPE, Str:Resource, quantity,price
		TransactionType t = o.transType();
		int quantity = o.quant();
		if(quantity<0) return false;
		//check trade type
		switch(t){
			case BUY:
				if(verifyBuy(o))
					return buy(o);
				break;
			case SELL:
				if(verifySell(o))
					return sell(o);
				break;
			case ACCEPT:
				if(verifyAccept(o))
					return accept(o);
				break; 
			case WITHDRAW:
				if(verifyWithdraw(o))
					return withdraw(o);
				break;
			default:
				//what?
				break;
		}  
		//how the hell are you reaching this?!?
		return false; 
	}

	boolean verifyBuy(Offer o){
		//verifyBuy hashes on the user name and gets the resources for that user
		String user = o.traderName();
		if(traderhash.get(user) == null)
			return false;

		int quantity = o.quant();
		int price = o.price();

		//if a user wants to buy an amount of resource that is less than or equal to zero, the transaction is invalid
		if(quantity <= 0) return false;
		//if the price is less than zero, buy is invalid
		if(price <0) return false;

		//a user is able to make the offer to buy if they have enough money
		String res = o.resource();
		if(traderhash.getResource(user, CASH) < quantity * price )
			return false;
		//check if someone is able to accept this order
		if(quantity < getMax(res))
			return false;

		//it hasn't failed, so...
		return true;  
	}


	boolean verifySell(Offer o){
		String user = o.traderName();
		//verify user exists
		if(traderhash.get(user) == null)
			return false;

		int quantity = o.quant();
		//valid quantity
		if(quantity <=0) return false;

		String res = o.resource();
		//verify seller has enough resources
		if(traderhash.getResource(user, res) < quantity)
			return false;

		return true;

	}


	boolean verifyAccept(Offer o){

		String user = o.traderName();
		String acceptor = o.acceptor();

		//verify user exists
		if(traderhash.get(acceptor) == null)
			return false;

		int quantity = o.quant();
		String res = o.resource();
		int price = o.price();


		//determine which is buyer/seller
		String buyer = o.transType() == BUY ? user : acceptor;
		String seller = buyer == user ? acceptor: user;

		//verify buyer has enough money
		int totalPrice = quantity * price;
		if(traderhash.getResource(buyer, CASH) < totalPrice)
			return false;

		//verify seller has enough
		if(traderhash.getResource(seller, res) < quantity)
			return false;


		return true;
	}


	boolean verifyWithdraw(Offer o){

		String user = o.traderName();
		String tradeID = o.tradeID();
		//verify trade is on list of available trades
		if(get(tradeID) == null)
			return false;

		return true;
	}


	boolean buy(Offer o){
		int quant = o.quant();
		int price = o.price();
		String user = o.traderName();

		//decrement offerers cash by the amount of ore they are offering to buy * the price
		OfferHandler.decrementResource(user, CASH, quant*price);

		//change to hash on ID given by trade system
		String ID = "CHANGE THIS";
		return put(ID, o);
	}


	boolean sell(Offer o){

		int quant = o.quant();
		int price = o.price();
		int res = o.resource();
		String user = o.traderName();
		//decrement the offerers' resource denoted in the sell offer by the quantity
		OfferHandler.decrementResource(user, res, quant );

		//should hash on ID given by trade system
		String ID = "CHANGE THIS";
		return put(ID, o);
	}


	boolean accept(Offer o){
		//change this
		String acceptor = o.acceptor();
		int quant = o.quant();
		int res = o.res();
		int price = o.res();

		//check transaction type to decrement the appropriate users resources
		if(o.transType == BUY){
			//we're selling
			OfferHandler.decrementResource(acceptor, res, quant);
		}else{
			//we're buying
			OfferHandler.decrementResource(acceptor, CASH, quant * price);
		}
		//log the offer in the list going to the audit system
		log(o);
		//notify users of successful trade
		NotifyUser(o.traderName());
		NotifyUser(o.acceptor());
		return true;
	}

	boolean withdraw(String id, String user){
		if(id == null || user == null) return false;
		//remove trade 

		Offer o = remove(id);

		if(o != null && o.traderName().equals(user)){
			if(o.res().equals(CASH)){
				OfferHandler.incrementResource(user, CASH, quant*price);
			}else{
				OfferHandler.incrementResource(user, res, quant );
			}
			return true;
		}
		//remove trade from list of avaailbale trades    
		return false;
	}


	int getMax(String resource){

		//CHANGE THIS-- should find the max of the resource in the trader hash
		return Integer.MAX_VALUE;
	}

	/*
	 * Log Accepted Offer
	 */

	private boolean log(Offer o){

		//instantiate
		if(log == null){
			log = new LinkedList<Offer>();
		}
		return log.add(o);
	}


}
